/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on Oct 17, 2006
* @author Fabio
*/
package org.python.pydev.navigator.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.ide.IDE;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.PyEdit;
import org.python.pydev.editor.actions.PyOpenAction;
import org.python.pydev.editor.model.ItemPointer;
import org.python.pydev.editor.model.Location;
import org.python.pydev.navigator.PythonpathTreeNode;
import org.python.pydev.navigator.PythonpathZipChildTreeNode;
import org.python.pydev.navigator.elements.PythonNode;
import org.python.pydev.outline.ParsedItem;
import org.python.pydev.parser.visitors.NodeUtils;
import org.python.pydev.parser.visitors.scope.ASTEntryWithChildren;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.ui.UIConstants;
/**
* This action will try to open a given file or node in the pydev editor (if a file or node is selected).
*
* If a container is selected, it will expand or collapse it.
*/
public class PyOpenPythonFileAction extends Action {
protected final List<IFile> filesSelected = new ArrayList<IFile>();
protected final List<PythonNode> nodesSelected = new ArrayList<PythonNode>();
protected final List<Object> containersSelected = new ArrayList<Object>(); // IContainer or IWrappedResource or PythonpathTreeNode(with folder file)
protected final List<PythonpathTreeNode> pythonPathFilesSelected = new ArrayList<PythonpathTreeNode>();
protected final List<PythonpathZipChildTreeNode> pythonPathZipFilesSelected = new ArrayList<PythonpathZipChildTreeNode>();
protected final ISelectionProvider provider;
public PyOpenPythonFileAction(IWorkbenchPage page, ISelectionProvider selectionProvider) {
this.setText("Open With Pydev (Python)");
this.setImageDescriptor(PydevPlugin.getImageCache().getDescriptor(UIConstants.PY_FILE_ICON));
this.provider = selectionProvider;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#isEnabled()
*/
public boolean isEnabled() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
public synchronized void run() {
// clear them
fillSelections();
if (filesSelected.size() > 0) {
openFiles(filesSelected);
} else if (nodesSelected.size() > 0) {
PythonNode node = nodesSelected.iterator().next();
ParsedItem actualObject = node.getActualObject();
ASTEntryWithChildren astThis = actualObject.getAstThis();
if (astThis != null) {
new PyOpenAction().run(new ItemPointer(node.getPythonFile().getActualObject(), NodeUtils
.getNameTokFromNode(astThis.node)));
}
} else if (pythonPathZipFilesSelected.size() > 0) {
openFiles(pythonPathZipFilesSelected.toArray(new PythonpathZipChildTreeNode[pythonPathZipFilesSelected
.size()]));
} else if (pythonPathFilesSelected.size() > 0) {
openFiles(pythonPathFilesSelected.toArray(new PythonpathTreeNode[pythonPathFilesSelected.size()]));
} else if (containersSelected.size() > 0) {
if (this.provider instanceof TreeViewer) {
TreeViewer viewer = (TreeViewer) this.provider;
for (Object container : containersSelected) {
if (viewer.isExpandable(container)) {
viewer.setExpandedState(container, !viewer.getExpandedState(container));
}
}
} else {
Log.log("Expecting the provider to be a TreeViewer -- it is:" + this.provider.getClass());
}
}
}
protected void openFiles(PythonpathZipChildTreeNode[] pythonPathZipFilesSelected) {
PyOpenAction pyOpenAction = new PyOpenAction();
for (PythonpathZipChildTreeNode n : pythonPathZipFilesSelected) {
pyOpenAction.run(new ItemPointer(n.zipStructure.file, new Location(), new Location(), null, n.zipPath));
}
}
protected void openFiles(PythonpathTreeNode[] pythonPathFilesSelected) {
PyOpenAction pyOpenAction = new PyOpenAction();
for (PythonpathTreeNode n : pythonPathFilesSelected) {
pyOpenAction.run(new ItemPointer(n.file));
}
}
/**
* Opens the given files with the Pydev editor.
*
* @param filesSelected the files to be opened with the pydev editor.
*/
protected void openFiles(List<IFile> filesSelected) {
for (IFile f : filesSelected) {
//If a file is opened here, set it as having the Pydev editor as the default editor.
IDE.setDefaultEditor(f, PyEdit.EDITOR_ID);
new PyOpenAction().run(new ItemPointer(f));
}
}
/**
* This method will get the given selection and fill the related attributes to match the selection correctly
* (files, nodes and containers).
*/
protected synchronized void fillSelections() {
filesSelected.clear();
nodesSelected.clear();
containersSelected.clear();
pythonPathFilesSelected.clear();
pythonPathZipFilesSelected.clear();
ISelection selection = provider.getSelection();
if (!selection.isEmpty()) {
IStructuredSelection sSelection = (IStructuredSelection) selection;
Iterator iterator = sSelection.iterator();
while (iterator.hasNext()) {
Object element = iterator.next();
if (element instanceof PythonNode) {
nodesSelected.add((PythonNode) element);
} else if (element instanceof PythonpathZipChildTreeNode) {
PythonpathZipChildTreeNode node = (PythonpathZipChildTreeNode) element;
if (node.isDir) {
containersSelected.add(node);
} else {
pythonPathZipFilesSelected.add(node);
}
} else if (element instanceof PythonpathTreeNode) {
PythonpathTreeNode node = (PythonpathTreeNode) element;
if (node.file.isFile()) {
pythonPathFilesSelected.add(node);
} else {
containersSelected.add(node);
}
} else if (element instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) element;
IFile file = (IFile) adaptable.getAdapter(IFile.class);
if (file != null) {
filesSelected.add(file);
} else {
IContainer container = (IContainer) adaptable.getAdapter(IContainer.class);
if (container != null) {
containersSelected.add(element);
}
}
}
}
}
}
/**
* @return whether the current selection enables this action (not considering selected containers).
*/
public boolean isEnabledForSelectionWithoutContainers() {
fillSelections();
if (filesSelected.size() > 0) {
for (IFile f : filesSelected) {
String name = f.getName();
if (name.indexOf('.') == -1) {
//Always add this menu if there's some file that doesn't have an extension.
return true;
}
}
}
if (nodesSelected.size() > 0 || pythonPathFilesSelected.size() > 0 || pythonPathZipFilesSelected.size() > 0) {
return true;
}
return false;
}
}